Skip to content

fix: multiple background tasks make outbound http re... in...#9021

Open
orbisai0security wants to merge 1 commit intomakeplane:previewfrom
orbisai0security:fix-ssrf-webhook-url-validation-v003
Open

fix: multiple background tasks make outbound http re... in...#9021
orbisai0security wants to merge 1 commit intomakeplane:previewfrom
orbisai0security:fix-ssrf-webhook-url-validation-v003

Conversation

@orbisai0security
Copy link
Copy Markdown

@orbisai0security orbisai0security commented May 5, 2026

Summary

Fix high severity security issue in apps/api/plane/bgtasks/webhook_task.py.

Vulnerability

Field Value
ID V-003
Severity HIGH
Scanner multi_agent_ai
Rule V-003
File apps/api/plane/bgtasks/webhook_task.py:333

Description: Multiple background tasks make outbound HTTP requests to URLs that may be user-supplied without validating that the destination is a legitimate external host. In webhook_task.py:333, the webhook.url value is user-configured and passed directly to requests.post() with no IP range or hostname validation. In work_item_link_task.py, URLs from work item links are fetched without restriction. An attacker can supply URLs pointing to internal services such as the AWS EC2 instance metadata endpoint (http://169.254.169.254/latest/meta-data/), internal Redis instances, or other private network services to exfiltrate credentials or interact with infrastructure not intended to be publicly accessible.

Changes

  • apps/api/plane/bgtasks/webhook_task.py

Verification

  • Build passes
  • Scanner re-scan confirms fix
  • LLM code review passed

Automated security fix by OrbisAI Security

Summary by CodeRabbit

  • Bug Fixes
    • Improved webhook handling by adding validation error detection. Webhooks with invalid URLs are now blocked earlier with appropriate logging, preventing unnecessary retry cycles and deactivation attempts.

Automated security fix generated by Orbis Security AI
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 5, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 5, 2026

📝 Walkthrough

Walkthrough

Added explicit ValueError exception handling in the webhook send task to detect and early-return when URL validation fails, preventing blocked webhooks from progressing to the request-retry flow.

Changes

Webhook URL Validation Error Handling

Layer / File(s) Summary
Exception Handling
apps/api/plane/bgtasks/webhook_task.py
Wrap send-time URL validation in try-except to catch ValueError, log "Webhook blocked", and return early, preventing downstream retry/deactivation logic.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐰 A rabbit stands guard at the webhook gate,
"Invalid URL? You cannot pass, I'm afraid!"
With one small catch, the path rings clear—
No retry storms, no blocked webhooks here. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is truncated ('fix: multiple background tasks make outbound http re... in...') and appears to be cut off, making it difficult to assess if it fully describes the main change of adding URL validation to prevent SSRF attacks. Complete the title with the full description, e.g., 'fix: add webhook URL validation to prevent SSRF attacks' to clearly convey the primary change.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The PR description provides comprehensive context about the security vulnerability (V-003), affected files, attack vectors, and verification steps performed, but does not follow the required template structure with Type of Change, Test Scenarios, and Screenshots sections.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/api/plane/bgtasks/webhook_task.py (1)

348-351: ⚡ Quick win

Persist blocked webhook attempts in save_webhook_log.

Line 348 returns early on validation failure, but this path currently skips persistent webhook logs. Adding a blocked-entry log keeps security blocks visible in the same audit stream as success/failure deliveries.

Proposed patch
     except ValueError as e:
         # URL failed SSRF/IP-range validation — do not send or retry
-        logger.error(f"Webhook {webhook.id} blocked: URL validation failed: {e}")
+        reason = f"URL validation failed: {e}"
+        save_webhook_log(
+            webhook=webhook,
+            request_method=action,
+            request_headers=headers,
+            request_body=payload,
+            response_status=403,
+            response_headers="",
+            response_body=reason,
+            retry_count=self.request.retries,
+            event_type=event,
+        )
+        logger.error(f"Webhook {webhook.id} blocked: {reason}")
         return
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/plane/bgtasks/webhook_task.py` around lines 348 - 351, The early
return in the except ValueError block for SSRF/IP-range validation prevents
persisting the blocked attempt; before returning from that block in
webhook_task.py (where logger.error logs "Webhook {webhook.id} blocked..."),
call the existing save_webhook_log function to persist a
blocked/validation-failed entry for this webhook (include webhook.id, the
request URL or target, the error message e, and a delivery status like "blocked"
or "validation_failed"), then return; this ensures blocked deliveries appear in
the same audit stream as successes/failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/api/plane/bgtasks/webhook_task.py`:
- Around line 348-351: The early return in the except ValueError block for
SSRF/IP-range validation prevents persisting the blocked attempt; before
returning from that block in webhook_task.py (where logger.error logs "Webhook
{webhook.id} blocked..."), call the existing save_webhook_log function to
persist a blocked/validation-failed entry for this webhook (include webhook.id,
the request URL or target, the error message e, and a delivery status like
"blocked" or "validation_failed"), then return; this ensures blocked deliveries
appear in the same audit stream as successes/failures.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5a36e423-1003-4fb3-94c7-4b1dbecb4b5c

📥 Commits

Reviewing files that changed from the base of the PR and between 9491bdb and 6e85367.

📒 Files selected for processing (1)
  • apps/api/plane/bgtasks/webhook_task.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants